home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / sound / nes_apu.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  20KB  |  800 lines

  1. /*****************************************************************************
  2.  
  3.   MAME/MESS NES APU CORE
  4.  
  5.   Based on the Nofrendo/Nosefart NES N2A03 sound emulation core written by
  6.   Matthew Conte (matt@conte.com) and redesigned for use in MAME/MESS by
  7.   Who Wants to Know? (wwtk@mail.com)
  8.  
  9.   This core is written with the advise and consent of Matthew Conte and is
  10.   released under the GNU Public License.  This core is freely avaiable for
  11.   use in any freeware project, subject to the following terms:
  12.  
  13.   Any modifications to this code must be duly noted in the source and
  14.   approved by Matthew Conte and myself prior to public submission.
  15.  
  16.  *****************************************************************************
  17.  
  18.    NES_APU.C
  19.  
  20.    Actual NES APU interface.
  21.  
  22.    LAST MODIFIED 12/24/1999
  23.  
  24.    - Initial public release of core, based on Matthew Conte's
  25.      Nofrendo/Nosefart core and redesigned to use MAME system calls
  26.      and to enable multiple APUs.  Sound at this point should be just
  27.      about 100% accurate, though I cannot tell for certain as yet.
  28.  
  29.      A queue interface is also available for additional speed.  However,
  30.      the implementation is not yet 100% (DPCM sounds are inaccurate),
  31.      so it is disabled by default.
  32.  
  33.  *****************************************************************************/
  34.  
  35. #include "driver.h"
  36. #include "nes_apu.h"
  37. #include "cpu/m6502/m6502.h"
  38.  
  39. /* UNCOMMENT THIS LINE TO ACTIVATE THE EVENT QUEUE. */
  40. /* IT SPEEDS UP THE EMULATION BUT COSTS SOME EXTRA MEMORY. */
  41. /* IT IS CURRENTLY DISABLED BECAUSE THE DPOCM DOESN'T WORK RIGHT WITH IT. */
  42. //#define USE_QUEUE
  43.  
  44. #include "nes_defs.h"
  45.  
  46. /* GLOBAL CONSTANTS */
  47. #define  SYNCS_MAX1     0x20
  48. #define  SYNCS_MAX2     0x80
  49.  
  50. /* GLOBAL VARIABLES */
  51. static apu_t   APU[MAX_NESPSG];       /* Actual APUs */
  52. static apu_t * cur;                   /* Pointer to an APU */
  53. static float   apu_incsize;           /* Adjustment increment */
  54. static uint16  samps_per_sync;        /* Number of samples per vsync */
  55. static uint16  buffer_size;           /* Actual buffer size in bytes */
  56. static uint16  real_rate;             /* Actual playback rate */
  57. static uint16  chip_max;              /* Desired number of chips in use */
  58. static uint8   noise_lut[NOISE_LONG]; /* Noise sample lookup table */
  59. static uint16  vbl_times[0x20];       /* VBL durations in samples */
  60. static uint32  sync_times1[SYNCS_MAX1]; /* Samples per sync table */
  61. static uint32  sync_times2[SYNCS_MAX2]; /* Samples per sync table */
  62. static int     channel;
  63.  
  64. #define SETAPU(x) cur = &APU[x]
  65.  
  66. #ifdef USE_QUEUE
  67. /* QUEUE-RELATED FUNCTIONS */
  68.  
  69. /* IS THE QUEUE EMPTY? */
  70. static char apu_queuenotempty(unsigned int chip)
  71. {
  72.   int head=APU[chip].head;
  73.  
  74.   if (APU[chip].head<APU[chip].tail) head+=QUEUE_SIZE;
  75.  
  76.   return (head-APU[chip].tail>1);
  77. }
  78.  
  79. /* IS THE QUEUE FULL? */
  80. static char apu_queuenotfull(unsigned int chip)
  81. {
  82.   int tail=APU[chip].tail;
  83.  
  84.   if (APU[chip].tail<APU[chip].head) tail+=QUEUE_SIZE;
  85.  
  86.   return (tail-APU[chip].head>1);
  87. }
  88.  
  89. /* ADD AN ENTRY TO THE QUEUE */
  90. INLINE void apu_enqueue(unsigned int chip,unsigned char reg,unsigned char val)
  91. {
  92.   queue_t *entry;
  93.  
  94.   SETAPU(chip);
  95.  
  96.   /* Only enqueue if it isn't full */
  97.   if (apu_queuenotfull(chip))
  98.   {
  99.     cur->head++;
  100.     cur->head&=QUEUE_MAX;
  101.     entry=&cur->queue[cur->head];
  102.     entry->pos=sound_scalebufferpos(samps_per_sync);
  103.     entry->reg=reg;
  104.     entry->val=val;
  105.   }
  106. }
  107.  
  108. /* EXTRACT AN ENTRY FROM THE QUEUE */
  109. INLINE queue_t * apu_dequeue(int chip)
  110. {
  111.   queue_t *p=&cur->queue[(cur->tail)];
  112.  
  113.   SETAPU(chip);
  114.  
  115.   /* Only increment if it isn't empty */
  116.   if (apu_queuenotempty(chip))
  117.   {
  118.     cur->tail++;
  119.     cur->tail&=QUEUE_MAX;
  120.   }
  121.   return p;
  122. }
  123.  
  124. #endif
  125.  
  126. /* INTERNAL FUNCTIONS */
  127.  
  128. /* INITIALIZE WAVE TIMES RELATIVE TO SAMPLE RATE */
  129. static void create_vbltimes(uint16 * table,const uint8 *vbl,unsigned int rate)
  130. {
  131.   int i;
  132.  
  133.   for (i=0;i<0x20;i++)
  134.     table[i]=vbl[i]*rate;
  135. }
  136.  
  137. /* INITIALIZE SAMPLE TIMES IN TERMS OF VSYNCS */
  138. static void create_syncs(unsigned long sps)
  139. {
  140.   int i;
  141.   unsigned long val=sps;
  142.  
  143.   for (i=0;i<SYNCS_MAX1;i++)
  144.   {
  145.     sync_times1[i]=val;
  146.     val+=sps;
  147.   }
  148.  
  149.   val=0;
  150.   for (i=0;i<SYNCS_MAX2;i++)
  151.   {
  152.     sync_times2[i]=val;
  153.     sync_times2[i]>>=2;
  154.     val+=sps;
  155.   }
  156. }
  157.  
  158. /* INITIALIZE NOISE LOOKUP TABLE */
  159. static void create_noise(uint8 *buf, const int bits, int size)
  160. {
  161.    static int m = 0x0011;
  162.    int xor_val, i;
  163.  
  164.    for (i = 0; i < size; i++)
  165.    {
  166.       xor_val = m & 1;
  167.       m >>= 1;
  168.       xor_val ^= (m & 1);
  169.       m |= xor_val << (bits - 1);
  170.  
  171.       buf[i] = m;
  172.    }
  173. }
  174.  
  175. /* TODO: sound channels should *ALL* have DC volume decay */
  176.  
  177. /* OUTPUT SQUARE WAVE SAMPLE (VALUES FROM -16 to +15) */
  178. static int8 apu_square(square_t *chan)
  179. {
  180.    int env_delay;
  181.    int sweep_delay;
  182.    int8 output;
  183.  
  184.    /* reg0: 0-3=volume, 4=envelope, 5=hold, 6-7=duty cycle
  185.    ** reg1: 0-2=sweep shifts, 3=sweep inc/dec, 4-6=sweep length, 7=sweep on
  186.    ** reg2: 8 bits of freq
  187.    ** reg3: 0-2=high freq, 7-4=vbl length counter
  188.    */
  189.  
  190.    if (FALSE == chan->enabled)
  191.       return 0;
  192.  
  193.    /* enveloping */
  194.    env_delay = sync_times1[chan->regs[0] & 0x0F];
  195.  
  196.    /* decay is at a rate of (env_regs + 1) / 240 secs */
  197.    chan->env_phase -= 4;
  198.    while (chan->env_phase < 0)
  199.    {
  200.       chan->env_phase += env_delay;
  201.       if (chan->regs[0] & 0x20)
  202.          chan->env_vol = (chan->env_vol + 1) & 15;
  203.       else if (chan->env_vol < 15)
  204.          chan->env_vol++;
  205.    }
  206.  
  207.    /* vbl length counter */
  208.    if (chan->vbl_length > 0 && 0 == (chan->regs [0] & 0x20))
  209.       chan->vbl_length--;
  210.  
  211.    if (0 == chan->vbl_length)
  212.       return 0;
  213.  
  214.    /* freqsweeps */
  215.    if ((chan->regs[1] & 0x80) && (chan->regs[1] & 7))
  216.    {
  217.       sweep_delay = sync_times1[(chan->regs[1] >> 4) & 7];
  218.       chan->sweep_phase -= 2;
  219.       while (chan->sweep_phase < 0)
  220.       {
  221.          chan->sweep_phase += sweep_delay;
  222.          if (chan->regs[1] & 8)
  223.             chan->freq -= chan->freq >> (chan->regs[1] & 7);
  224.          else
  225.             chan->freq += chan->freq >> (chan->regs[1] & 7);
  226.       }
  227.    }
  228.  
  229.    if ((0 == (chan->regs[1] & 8) && (chan->freq >> 16) > freq_limit[chan->regs[1] & 7])
  230.        || (chan->freq >> 16) < 4)
  231.       return 0;
  232.  
  233.    chan->phaseacc -= (float) apu_incsize; /* # of cycles per sample */
  234.  
  235.    while (chan->phaseacc < 0)
  236.    {
  237.       chan->phaseacc += (chan->freq >> 16);
  238.       chan->adder = (chan->adder + 1) & 0x0F;
  239.    }
  240.  
  241.    if (chan->regs[0] & 0x10) /* fixed volume */
  242.       output = chan->regs[0] & 0x0F;
  243.    else
  244.       output = 0x0F - chan->env_vol;
  245.  
  246.    if (chan->adder < (duty_lut[chan->regs[0] >> 6]))
  247.       output = -output;
  248.  
  249.    return (int8) output;
  250. }
  251.  
  252. /* OUTPUT TRIANGLE WAVE SAMPLE (VALUES FROM -16 to +15) */
  253. static int8 apu_triangle(triangle_t *chan)
  254. {
  255.    int freq;
  256.    int8 output;
  257.    /* reg0: 7=holdnote, 6-0=linear length counter
  258.    ** reg2: low 8 bits of frequency
  259.    ** reg3: 7-3=length counter, 2-0=high 3 bits of frequency
  260.    */
  261.  
  262.    if (FALSE == chan->enabled)
  263.       return 0;
  264.  
  265.    if (FALSE == chan->counter_started && 0 == (chan->regs[0] & 0x80))
  266.    {
  267.       if (chan->write_latency)
  268.          chan->write_latency--;
  269.       if (0 == chan->write_latency)
  270.          chan->counter_started = TRUE;
  271.    }
  272.  
  273.    if (chan->counter_started)
  274.    {
  275.       if (chan->linear_length > 0)
  276.          chan->linear_length--;
  277.       if (chan->vbl_length && 0 == (chan->regs[0] & 0x80))
  278.             chan->vbl_length--;
  279.  
  280.       if (0 == chan->vbl_length)
  281.          return 0;
  282.    }
  283.  
  284.    if (0 == chan->linear_length)
  285.       return 0;
  286.  
  287.    freq = (((chan->regs[3] & 7) << 8) + chan->regs[2]) + 1;
  288.  
  289.    if (freq < 4) /* inaudible */
  290.       return 0;
  291.  
  292.    chan->phaseacc -= (float) apu_incsize; /* # of cycles per sample */
  293.    while (chan->phaseacc < 0)
  294.    {
  295.       chan->phaseacc += freq;
  296.       chan->adder = (chan->adder + 1) & 0x1F;
  297.  
  298.       output = (chan->adder & 7) << 1;
  299.       if (chan->adder & 8)
  300.          output = 0x10 - output;
  301.       if (chan->adder & 0x10)
  302.          output = -output;
  303.  
  304.       chan->output_vol = output;
  305.    }
  306.  
  307.    return (int8) chan->output_vol;
  308. }
  309.  
  310. /* OUTPUT NOISE WAVE SAMPLE (VALUES FROM -16 to +15) */
  311. static int8 apu_noise(noise_t *chan)
  312. {
  313.    int freq, env_delay;
  314.    uint8 outvol;
  315.    uint8 output;
  316.  
  317.    /* reg0: 0-3=volume, 4=envelope, 5=hold
  318.    ** reg2: 7=small(93 byte) sample,3-0=freq lookup
  319.    ** reg3: 7-4=vbl length counter
  320.    */
  321.  
  322.    if (FALSE == chan->enabled)
  323.       return 0;
  324.  
  325.    /* enveloping */
  326.    env_delay = sync_times1[chan->regs[0] & 0x0F];
  327.  
  328.    /* decay is at a rate of (env_regs + 1) / 240 secs */
  329.    chan->env_phase -= 4;
  330.    while (chan->env_phase < 0)
  331.    {
  332.       chan->env_phase += env_delay;
  333.       if (chan->regs[0] & 0x20)
  334.          chan->env_vol = (chan->env_vol + 1) & 15;
  335.       else if (chan->env_vol < 15)
  336.          chan->env_vol++;
  337.    }
  338.  
  339.    /* length counter */
  340.    if (0 == (chan->regs[0] & 0x20))
  341.    {
  342.       if (chan->vbl_length > 0)
  343.          chan->vbl_length--;
  344.    }
  345.  
  346.    if (0 == chan->vbl_length)
  347.       return 0;
  348.  
  349.    freq = noise_freq[chan->regs[2] & 0x0F];
  350.    chan->phaseacc -= (float) apu_incsize; /* # of cycles per sample */
  351.    while (chan->phaseacc < 0)
  352.    {
  353.       chan->phaseacc += freq;
  354.  
  355.       chan->cur_pos++;
  356.       if (NOISE_SHORT == chan->cur_pos && (chan->regs[2] & 0x80))
  357.          chan->cur_pos = 0;
  358.       else if (NOISE_LONG == chan->cur_pos)
  359.          chan->cur_pos = 0;
  360.    }
  361.  
  362.    if (chan->regs[0] & 0x10) /* fixed volume */
  363.       outvol = chan->regs[0] & 0x0F;
  364.    else
  365.       outvol = 0x0F - chan->env_vol;
  366.  
  367.    output = noise_lut[chan->cur_pos];
  368.    if (output > outvol)
  369.       output = outvol;
  370.  
  371.    if (noise_lut[chan->cur_pos] & 0x80) /* make it negative */
  372.       output = -output;
  373.  
  374.    return (int8) output;
  375. }
  376.  
  377. /* RESET DPCM PARAMETERS */
  378. INLINE void apu_dpcmreset(dpcm_t *chan)
  379. {
  380.    chan->address = 0xC000 + (uint16) (chan->regs[2] << 6);
  381.    chan->length = (uint16) (chan->regs[3] << 4) + 1;
  382.    chan->bits_left = chan->length << 3;
  383.    chan->irq_occurred = FALSE;
  384. }
  385.  
  386. /* OUTPUT DPCM WAVE SAMPLE (VALUES FROM -64 to +63) */
  387. /* TODO: centerline naughtiness */
  388. static int8 apu_dpcm(dpcm_t *chan)
  389. {
  390.    int freq, bit_pos;
  391.  
  392.    /* reg0: 7=irq gen, 6=looping, 3-0=pointer to clock table
  393.    ** reg1: output dc level, 7 bits unsigned
  394.    ** reg2: 8 bits of 64-byte aligned address offset : $C000 + (value * 64)
  395.    ** reg3: length, (value * 16) + 1
  396.    */
  397.  
  398.    if (chan->enabled)
  399.    {
  400.       freq = dpcm_clocks[chan->regs[0] & 0x0F];
  401.       chan->phaseacc -= (float) apu_incsize; /* # of cycles per sample */
  402.  
  403.       while (chan->phaseacc < 0)
  404.       {
  405.          chan->phaseacc += freq;
  406.  
  407.          if (0 == chan->length)
  408.          {
  409.             if (chan->regs[0] & 0x40)
  410.                apu_dpcmreset(chan);
  411.             else
  412.             {
  413.                if (chan->regs[0] & 0x80) /* IRQ Generator */
  414.                {
  415.                   chan->irq_occurred = TRUE;
  416.                   n2a03_irq();
  417.                }
  418.                break;
  419.             }
  420.          }
  421.  
  422.          chan->bits_left--;
  423.          bit_pos = 7 - (chan->bits_left & 7);
  424.          if (7 == bit_pos)
  425.          {
  426.             chan->cur_byte = chan->cpu_mem[chan->address];
  427.             chan->address++;
  428.             chan->length--;
  429.          }
  430.  
  431.          if (chan->cur_byte & (1 << bit_pos))
  432. //            chan->regs[1]++;
  433.             chan->vol++;
  434.          else
  435. //            chan->regs[1]--;
  436.             chan->vol--;
  437.       }
  438.    }
  439.  
  440.    if (chan->vol > 63)
  441.       chan->vol = 63;
  442.    else if (chan->vol < -64)
  443.       chan->vol = -64;
  444.  
  445.    return (int8) (chan->vol >> 1);
  446. }
  447.  
  448. /* WRITE REGISTER VALUE */
  449. INLINE void apu_regwrite(int chip,int address, uint8 value)
  450. {
  451.    int chan = (address & 4) ? 1 : 0;
  452.  
  453.    SETAPU(chip);
  454.    switch (address)
  455.    {
  456.    /* squares */
  457.    case APU_WRA0:
  458.    case APU_WRB0:
  459.       cur->squ[chan].regs[0] = value;
  460.       break;
  461.  
  462.    case APU_WRA1:
  463.    case APU_WRB1:
  464.       cur->squ[chan].regs[1] = value;
  465.       break;
  466.  
  467.    case APU_WRA2:
  468.    case APU_WRB2:
  469.       cur->squ[chan].regs[2] = value;
  470.       if (cur->squ[chan].enabled)
  471.          cur->squ[chan].freq = ((((cur->squ[chan].regs[3] & 7) << 8) + value) + 1) << 16;
  472.       break;
  473.  
  474.    case APU_WRA3:
  475.    case APU_WRB3:
  476.       cur->squ[chan].regs[3] = value;
  477.  
  478.       if (cur->squ[chan].enabled)
  479.       {
  480.          cur->squ[chan].vbl_length = vbl_times[value >> 3];
  481.          cur->squ[chan].env_vol = 0;
  482.          cur->squ[chan].freq = ((((value & 7) << 8) + cur->squ[chan].regs[2]) + 1) << 16;
  483.       }
  484.  
  485.       break;
  486.  
  487.    /* triangle */
  488.    case APU_WRC0:
  489.       cur->tri.regs[0] = value;
  490.  
  491.       if (cur->tri.enabled)
  492.       {                                          /* ??? */
  493.          if (FALSE == cur->tri.counter_started)
  494.             cur->tri.linear_length = sync_times2[value & 0x7F];
  495.       }
  496.  
  497.       break;
  498.  
  499.    case 0x4009:
  500.       /* unused */
  501.       cur->tri.regs[1] = value;
  502.       break;
  503.  
  504.    case APU_WRC2:
  505.       cur->tri.regs[2] = value;
  506.       break;
  507.  
  508.    case APU_WRC3:
  509.       cur->tri.regs[3] = value;
  510.  
  511.       /* this is somewhat of a hack.  there is some latency on the Real
  512.       ** Thing between when trireg0 is written to and when the linear
  513.       ** length counter actually begins its countdown.  we want to prevent
  514.       ** the case where the program writes to the freq regs first, then
  515.       ** to reg 0, and the counter accidentally starts running because of
  516.       ** the sound queue's timestamp processing.
  517.       **
  518.       ** set to a few NES sample -- should be sufficient
  519.       **
  520.       **     3 * (1789772.727 / 44100) = ~122 cycles, just around one scanline
  521.       **
  522.       ** should be plenty of time for the 6502 code to do a couple of table
  523.       ** dereferences and load up the other triregs
  524.       */
  525.  
  526.       cur->tri.write_latency = 3;
  527.  
  528.       if (cur->tri.enabled)
  529.       {
  530.          cur->tri.counter_started = FALSE;
  531.          cur->tri.vbl_length = vbl_times[value >> 3];
  532.          cur->tri.linear_length = sync_times2[cur->tri.regs[0] & 0x7F];
  533.       }
  534.  
  535.       break;
  536.  
  537.    /* noise */
  538.    case APU_WRD0:
  539.       cur->noi.regs[0] = value;
  540.       break;
  541.  
  542.    case 0x400D:
  543.       /* unused */
  544.       cur->noi.regs[1] = value;
  545.       break;
  546.  
  547.    case APU_WRD2:
  548.       cur->noi.regs[2] = value;
  549.       break;
  550.  
  551.    case APU_WRD3:
  552.       cur->noi.regs[3] = value;
  553.  
  554.       if (cur->noi.enabled)
  555.       {
  556.          cur->noi.vbl_length = vbl_times[value >> 3];
  557.          cur->noi.env_vol = 0; /* reset envelope */
  558.       }
  559.       break;
  560.  
  561.    /* DMC */
  562.    case APU_WRE0:
  563.       cur->dpcm.regs[0] = value;
  564.       if (0 == (value & 0x80))
  565.          cur->dpcm.irq_occurred = FALSE;
  566.       break;
  567.  
  568.    case APU_WRE1: /* 7-bit DAC */
  569.       //cur->dpcm.regs[1] = value - 0x40;
  570.       cur->dpcm.regs[1] = value & 0x7F;
  571.       cur->dpcm.vol = (cur->dpcm.regs[1]-64);
  572.       break;
  573.  
  574.    case APU_WRE2:
  575.       cur->dpcm.regs[2] = value;
  576.       //apu_dpcmreset(cur->dpcm);
  577.       break;
  578.  
  579.    case APU_WRE3:
  580.       cur->dpcm.regs[3] = value;
  581.       //apu_dpcmreset(cur->dpcm);
  582.       break;
  583.  
  584.    case APU_SMASK:
  585.       if (value & 0x01)
  586.          cur->squ[0].enabled = TRUE;
  587.       else
  588.       {
  589.          cur->squ[0].enabled = FALSE;
  590.          cur->squ[0].vbl_length = 0;
  591.       }
  592.  
  593.       if (value & 0x02)
  594.          cur->squ[1].enabled = TRUE;
  595.       else
  596.       {
  597.          cur->squ[1].enabled = FALSE;
  598.          cur->squ[1].vbl_length = 0;
  599.       }
  600.  
  601.       if (value & 0x04)
  602.          cur->tri.enabled = TRUE;
  603.       else
  604.       {
  605.          cur->tri.enabled = FALSE;
  606.          cur->tri.vbl_length = 0;
  607.          cur->tri.linear_length = 0;
  608.          cur->tri.counter_started = FALSE;
  609.          cur->tri.write_latency = 0;
  610.       }
  611.  
  612.       if (value & 0x08)
  613.          cur->noi.enabled = TRUE;
  614.       else
  615.       {
  616.          cur->noi.enabled = FALSE;
  617.          cur->noi.vbl_length = 0;
  618.       }
  619.  
  620.       if (value & 0x10)
  621.       {
  622.          /* only reset dpcm values if DMA is finished */
  623.          if (FALSE == cur->dpcm.enabled)
  624.          {
  625.             cur->dpcm.enabled = TRUE;
  626.             apu_dpcmreset(&cur->dpcm);
  627.          }
  628.       }
  629.       else
  630.          cur->dpcm.enabled = FALSE;
  631.  
  632.       cur->dpcm.irq_occurred = FALSE;
  633.  
  634.       break;
  635.    default:
  636. #ifdef MAME_DEBUG
  637. logerror("invalid apu write: $%02X at $%04X\n", value, address);
  638. #endif
  639.       break;
  640.    }
  641. }
  642.  
  643. /* UPDATE SOUND BUFFER USING CURRENT DATA */
  644. INLINE void apu_update(int chip)
  645. {
  646.    static INT16 *buffer16 = NULL;
  647.    int accum;
  648.    int endp = sound_scalebufferpos(samps_per_sync);
  649.    int elapsed;
  650.  
  651. #ifdef USE_QUEUE
  652.    queue_t *q=NULL;
  653.  
  654.    elapsed=0;
  655. #endif
  656.  
  657.    SETAPU(chip);
  658.    buffer16  = cur->buffer;
  659.  
  660. #ifndef USE_QUEUE
  661.    /* Recall last position updated and restore pointers */
  662.    elapsed = cur->buf_pos;
  663.    buffer16 += elapsed;
  664. #endif
  665.  
  666.    while (elapsed<endp)
  667.    {
  668. #ifdef USE_QUEUE
  669.       while (apu_queuenotempty(chip) && (cur->queue[cur->head].pos==elapsed))
  670.       {
  671.          q = apu_dequeue(chip);
  672.          apu_regwrite(chip,q->reg,q->val);
  673.       }
  674. #endif
  675.       elapsed++;
  676.  
  677.       accum = apu_square(&cur->squ[0]);
  678.       accum += apu_square(&cur->squ[1]);
  679.       accum += apu_triangle(&cur->tri);
  680.       accum += apu_noise(&cur->noi);
  681.       accum += apu_dpcm(&cur->dpcm);
  682.  
  683.       /* 8-bit clamps */
  684.       if (accum > 127)
  685.          accum = 127;
  686.       else if (accum < -128)
  687.          accum = -128;
  688.  
  689.       *(buffer16++)=accum<<8;
  690.    }
  691. #ifndef USE_QUEUE
  692.    cur->buf_pos = endp;
  693. #endif
  694. }
  695.  
  696. /* READ VALUES FROM REGISTERS */
  697. INLINE uint8 apu_read(int chip,int address)
  698. {
  699.   return APU[chip].regs[address];
  700. }
  701.  
  702. /* WRITE VALUE TO TEMP REGISTRY AND QUEUE EVENT */
  703. INLINE void apu_write(int chip,int address, uint8 value)
  704. {
  705.    APU[chip].regs[address]=value;
  706. #ifdef USE_QUEUE
  707.    apu_enqueue(chip,address,value);
  708. #else
  709.    apu_update(chip);
  710.    apu_regwrite(chip,address,value);
  711. #endif
  712. }
  713.  
  714. /* EXTERNAL INTERFACE FUNCTIONS */
  715.  
  716. /* REGISTER READ/WRITE FUNCTIONS */
  717. READ_HANDLER( NESPSG_0_r ) {return apu_read(0,offset);}
  718. READ_HANDLER( NESPSG_1_r ) {return apu_read(1,offset);}
  719. WRITE_HANDLER( NESPSG_0_w ) {apu_write(0,offset,data);}
  720. WRITE_HANDLER( NESPSG_1_w ) {apu_write(1,offset,data);}
  721.  
  722. /* INITIALIZE APU SYSTEM */
  723. int NESPSG_sh_start(const struct MachineSound *msound)
  724. {
  725.   struct NESinterface *intf = msound->sound_interface;
  726.   int i;
  727.  
  728.   /* Initialize global variables */
  729.   samps_per_sync = Machine->sample_rate / Machine->drv->frames_per_second;
  730.   buffer_size = samps_per_sync;
  731.   real_rate = samps_per_sync * Machine->drv->frames_per_second;
  732.   chip_max = intf->num;
  733.   apu_incsize = (float) (N2A03_DEFAULTCLOCK / (float) real_rate);
  734.  
  735.   /* Use initializer calls */
  736.   create_noise(noise_lut, 13, NOISE_LONG);
  737.   create_vbltimes(vbl_times,vbl_length,samps_per_sync);
  738.   create_syncs(samps_per_sync);
  739.  
  740.   /* Adjust buffer size if 16 bits */
  741.   buffer_size+=samps_per_sync;
  742.  
  743.   /* Initialize individual chips */
  744.   for (i = 0;i < chip_max;i++)
  745.   {
  746.      SETAPU(i);
  747.  
  748.      memset(cur,0,sizeof(apu_t));
  749.  
  750.      /* Check for buffer allocation failure and bail out if necessary */
  751.      if ((cur->buffer = malloc(buffer_size))==NULL)
  752.      {
  753.        while (--i >= 0) free(APU[i].buffer);
  754.        return 1;
  755.      }
  756.  
  757. #ifdef USE_QUEUE
  758.      cur->head=0;cur->tail=QUEUE_MAX;
  759. #endif
  760.      (cur->dpcm).cpu_mem=memory_region(intf->region[i]);
  761.   }
  762.  
  763.   channel = mixer_allocate_channels(chip_max,intf->volume);
  764.   for (i = 0;i < chip_max;i++)
  765.   {
  766.     char name[40];
  767.  
  768.     sprintf(name,"%s #%d",sound_name(msound),i);
  769.     mixer_set_name(channel,name);
  770.   }
  771.  
  772.   return 0;
  773. }
  774.  
  775. /* HALT APU SYSTEM */
  776. void NESPSG_sh_stop(void)
  777. {
  778.   int i;
  779.  
  780.   for (i=0;i<chip_max;i++)
  781.     free(APU[i].buffer);
  782. }
  783.  
  784. /* UPDATE APU SYSTEM */
  785. void NESPSG_sh_update(void)
  786. {
  787.   int i;
  788.  
  789.   if (real_rate==0) return;
  790.  
  791.   for (i = 0;i < chip_max;i++)
  792.   {
  793.     apu_update(i);
  794. #ifndef USE_QUEUE
  795.     APU[i].buf_pos=0;
  796. #endif
  797.     mixer_play_streamed_sample_16(channel+i,APU[i].buffer,buffer_size,real_rate);
  798.   }
  799. }
  800.